package com.itheima.d10_api_object;

/**
 * public Object clone()
 *     克隆当前对象，返回一个新对象
 *
 * 浅克隆：
 * 拷贝出来的对象封装的数据与原对象封装的数据一模一样（引用类型拷贝的是地址值）
 * 比如本案例中的username和password字符串是放在字符串常量池中的,scores数组则是在堆内存中new出来的对象
 * 所以这三个都记录了各自的地址，在浅克隆的时候，就会把这三个地址分别复制一份过来，指向的都是同一个对象
 *
 * 深克隆：
 * 对象中基本类型的数据直接拷贝。
 * 对象中的字符串数据拷贝的还是地址。因为字符串是不可变的，还是在字符串常量池中共享
 * 对象中还包含的其他对象，不会拷贝地址，会创建新对象。例如本案例的数组对象，会创建一个新的数组对象拷贝过来值
 */
// Cloneable是一个标记接口(意思就是这个接口中什么都没有)。想要调用clone()方法，必须让被克隆的类实现Cloneable接口。

public class User implements Cloneable{
    private int id; // 编号
    private String username; // 用户名
    private String password; // 密码
    private double[] scores; // 分数

    public User(){}

    public User(int id, String username,
                String password, double[] scores) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.scores = scores;
    }

    //深克隆的方法
    protected Object clone1() throws CloneNotSupportedException {
        // super去调用父类Object中的clone方法。先克隆得到一个新对象
        User u2 = (User) super.clone();
        //再将新对象中的引用类型数据，再次克隆
        u2.scores = u2.scores.clone();
        return u2;
    }

    //系统默认的重写的clone方法 浅克隆
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // super去调用父类Object中的clone方法。
        return super.clone();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double[] getScores() {
        return scores;
    }

    public void setScores(double[] scores) {
        this.scores = scores;
    }
}
